/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[欢迎加盟知启蒙，一起邂逅框架梦]
 * 
 * https://www.zhiqim.com/gitcan/zhiqim/zhiqim_account.htm
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.zhiqim.account.api.connect;

import java.sql.SQLException;

import org.zhiqim.account.ZacConstants;
import org.zhiqim.kernel.httpclient.HttpGet;
import org.zhiqim.kernel.httpclient.HttpResult;
import org.zhiqim.kernel.json.Jsons;
import org.zhiqim.kernel.util.Asserts;
import org.zhiqim.kernel.util.Strings;
import org.zhiqim.kernel.util.Urls;
import org.zhiqim.manager.dao.ZmrParamDao;
import org.zhiqim.orm.ORMException;

/**
 * 微信授权后接口调用
 * https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419316518&lang=zh_CN
 *
 * @version v1.0.0 @author yangpeng 2018-1-26 新建与整理
 */
public class WxService implements ZacConstants
{
    /**
     * 微信公众号授权，获取访问令牌
     * 
     * @param code          微信公众平台回调时传入的编码
     * @return              通过编码进行授权得到结果
     * @throws SQLException 数据库异常
     * @throws ORMException 数据库异常
     */
    public static HttpResult getAccessTokenByMP(String code) throws ORMException, SQLException
    {
        String appId = ZmrParamDao.getString(ZAC_NAME, WXMP_APP_ID);
        String appSecret = ZmrParamDao.getString(ZAC_NAME, WXMP_APP_SECRET);
        
        //诊断配置
        Asserts.assertNotEmptyBlank(appId, QQ_CONF_ERR);
        Asserts.assertNotEmptyBlank(appSecret, QQ_CONF_ERR);
        
        return getAccessToken(code, appId, appSecret);
    }
    
    /**
     * 微信开放平台授权，获取访问令牌
     * 
     * @param code          微信开放平台回调时传入的编码
     * @return              通过编码进行授权得到结果
     * @throws SQLException 数据库异常
     * @throws ORMException 数据库异常
     */
    public static HttpResult getAccessTokenByOpen(String code) throws ORMException, SQLException
    {
        String appId = ZmrParamDao.getString(ZAC_NAME, WXOP_APP_ID);
        String appSecret = ZmrParamDao.getString(ZAC_NAME, WXOP_APP_SECRET);
        
        //诊断配置
        Asserts.assertNotEmptyBlank(appId, QQ_CONF_ERR);
        Asserts.assertNotEmptyBlank(appSecret, QQ_CONF_ERR);
        
        return getAccessToken(code, appId, appSecret);
    }
    
    /**
     * 授权，获取访问令牌，微信开放平台和微信公众号URL相同，传入各自的appId&appSecret即可
     * 
     * @param code      微信开放平台回调时传入的编码
     * @param appId     微信开放平台或公众号的appId
     * @param appSecret 微信开放平台或公众号的appSecret
     * @return          通过编码进行授权得到结果
     */
    public static HttpResult getAccessToken(String code, String appId, String appSecret)
    {
        String url = Strings.formatMessage(WXOP_URL_TOKEN, appId, appSecret, code);
        HttpGet conn = new HttpGet(url);
        conn.setConnectTimeout(10);
        conn.setReadTimeout(30);
        conn.setConnectionClose();
        conn.execute();
        
        if (conn.isResponseSuccess())
        {//调用不成功
            return conn.getResult();
        }
        
        //成功判断错误码
        String responseText = conn.getResponseText();
        int errcode = Jsons.getInt(responseText, "errcode", 0);
        if(errcode != 0)
            return new HttpResult(errcode, Urls.get(responseText, "errmsg"));
        else
            return conn.getResult();
    }
    
    /**
     * 获取用户个人信息（UnionID机制）
     * @param accessToken 调用凭证
     * @param openId 普通用户的标识，对当前开发者帐号唯一
     * @return
     */
    public static HttpResult getUserInfo(String accessToken, String openId)
    {
        String url = Strings.formatMessage(WXOP_URL_GET_USER_INFO, accessToken, openId);
        HttpGet conn = new HttpGet(url);
        conn.setConnectTimeout(10);
        conn.setReadTimeout(30);
        conn.setConnectionClose();
        conn.execute();
        
        if (conn.isResponseSuccess())
        {//调用不成功
            return conn.getResult();
        }
        
        //成功判断错误码
        String responseText = conn.getResponseText();
        int errcode = Jsons.getInt(responseText, "errcode", 0);
        if(errcode != 0)
            return new HttpResult(errcode, Urls.get(responseText, "errmsg"));
        else
            return conn.getResult();
    }
}
